package edu.cmu.ibill.model;

import org.mybeans.dao.DAOException;
import org.mybeans.factory.BeanFactory;
import org.mybeans.factory.BeanFactoryException;
import org.mybeans.factory.BeanTable;
import org.mybeans.factory.MatchArg;
import org.mybeans.factory.RollbackException;
import org.mybeans.factory.Transaction;

import edu.cmu.ibill.databeans.*;

/**
 * 
 * @author Yunkai Zhang
 * 
 */
public class DebtDAO {

	private BeanFactory<Debt> factory;

	/**
	 * Constructor
	 * 
	 * @param driver
	 * @param URL
	 * @param user
	 * @param pw
	 * @throws DAOException
	 */
	public DebtDAO(String driver, String URL, String user, String pw)
			throws DAOException {
		try {
			// Get a BeanTable to create the "photo" table

			BeanTable.useJDBC(driver, URL, user, pw);

			BeanTable<Debt> debtTable = BeanTable.getInstance(Debt.class,
					"ibill_debt");

			if (!debtTable.exists()) {
				debtTable.create("id");
			}

			debtTable.setIdleConnectionCleanup(true);

			// Get a BeanFactory which the actions will use to read and write
			// rows of the "likeable" table
			factory = debtTable.getFactory();
		} catch (BeanFactoryException e) {
			throw new DAOException(e);
		}
	}

	/**
	 * Lookup the debt using the debt id.
	 * 
	 * @param id
	 * @return Debt
	 */
	public Debt Lookup(int id) {
		Debt debt = null;

		try {
			Debt[] list = factory.match(MatchArg.equals("id", id));
			if (list.length > 0)
				debt = list[0];
		} catch (RollbackException e) {
			return null;
		}

		return debt;
	}

	/**
	 * Return all the debts payed by one user
	 * 
	 * @param pid
	 * @return Debt[]
	 */
	public Debt[] LookupByPayedId(int pid) {
		Debt[] debts = null;

		try {
			debts = factory.match(MatchArg.equals("payedId", pid));
		} catch (RollbackException e) {
			return null;
		}
		return debts;
	}
	
	

	/**
	 * Return all the debts owed by one user
	 * 
	 * @param oid
	 * @return Debt[]
	 */
	public Debt[] LookupByOwedId(int oid) {
		Debt[] debts = null;

		try {
			debts = factory.match(MatchArg.equals("owedId", oid));
		} catch (RollbackException e) {
			return null;
		}
		return debts;
	}
	
	/**
	 * Return the debt associated with the given owed bill id
	 * 
	 * @param oid
	 * @return Debt[]
	 */
	public Debt LookupByOwedBillId(int obid) {
		Debt debt = null;

		try {
			Debt[] list = factory.match(MatchArg.equals("owedbillId", obid));
			if(list!=null && list.length > 0)
				debt = list[1];
		} catch (RollbackException e) {
			return null;
		}
		return debt;
	}

	
	/**
	 * Return the debt associated with the given payed bill id
	 * 
	 * @param oid
	 * @return Debt[]
	 */
	public Debt LookupByPayedBillId(int pbid) {
		Debt debt = null;

		try {
			Debt[] list = factory.match(MatchArg.equals("payedbillId", pbid));
			if(list!=null && list.length > 0)
				debt = list[0];
		} catch (RollbackException e) {
			return null;
		}
		return debt;
	}


	/**
	 * Insert a debt into the database
	 * 
	 * @param debt
	 * @throws DAOException
	 */
	public void create(Debt debt) throws DAOException {
		try {
			Transaction.begin();

			Debt dbDebt = factory.create();
			factory.copyInto(debt, dbDebt);

			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}

	/**
	 * Update the debt in the database
	 * 
	 * @param debt
	 * @throws DAOException
	 */
	public void update(Debt debt) throws DAOException {
		try {
			Transaction.begin();

			Debt dbDebt = factory.lookup(debt.getId());

			if (dbDebt == null)
				throw new DAOException("Cannot find the Debt: " + debt.getId());

			factory.copyInto(debt, dbDebt);

			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}

	/**
	 * Delete the Debt from Database.
	 * 
	 * @param id
	 * @throws DAOException
	 */
	public void delete(int id) throws DAOException {
		try {
			factory.delete(id);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}

}
